package processor

import (
	"context"
	"encoding/json"
	"time"
)

// Job 定时任务
type Job struct {
	Name    string `json:"name"`    //  任务名
	Command string `json:"command"` // shell命令
	RunAt   string `json:"run_at"`  // cron表达式
}

// JobSchedulePlan 任务调度计划
type JobSchedulePlan struct {
	Job   *Job      // 要调度的任务信息
	RunAt time.Time // 调度时间
}

// JobExecuteInfo 任务执行状态
type JobExecuteInfo struct {
	Job        *Job               // 任务信息
	PlanTime   time.Time          // 理论上的调度时间
	RealTime   time.Time          // 实际的调度时间
	CancelCtx  context.Context    // 任务command的context
	CancelFunc context.CancelFunc //  用于取消command执行的cancel函数
}

// Response HTTP接口应答
type Response struct {
	Errno int         `json:"errno"`
	Msg   string      `json:"msg"`
	Data  interface{} `json:"data"`
}

// JobEvent 变化事件
type JobEvent struct {
	EventType int //  SAVE, DELETE
	Job       *Job
}

// JobExecuteResult 任务执行结果
type JobExecuteResult struct {
	ExecuteInfo *JobExecuteInfo // 执行状态
	Output      []byte          // 脚本输出
	Err         error           // 脚本错误原因
	StartTime   time.Time       // 启动时间
	EndTime     time.Time       // 结束时间
}

// JobLog 任务执行日志
type JobLog struct {
	JobName      string `json:"jobName" gorm:"column:job_name;type:varchar(255)"`           // 任务名字
	Command      string `json:"command" gorm:"column:command;type:varchar(255)"`            // 脚本命令
	Err          string `json:"err" bson:"column:err;type:varchar(255)"`                    // 错误原因
	Output       string `json:"output" gorm:"column:output;type:varchar(255)"`              // 脚本输出
	PlanTime     int64  `json:"planTime" gorm:"column:plan_time;type:varchar(255)"`         // 计划开始时间
	ScheduleTime int64  `json:"scheduleTime" gorm:"column:schedule_time;type:varchar(255)"` // 实际调度时间
	StartTime    int64  `json:"startTime" gorm:"column:start_time;type:varchar(255)"`       // 任务执行开始时间
	EndTime      int64  `json:"endTime" gorm:"end_time;type:varchar(255)"`                  // 任务执行结束时间
}

// LogBatch 日志批次
type LogBatch struct {
	Logs []interface{} // 多条日志
}

// JobLogFilter 任务日志过滤条件
type JobLogFilter struct {
	JobName string `bson:"jobName"`
}

// SortLogByStartTime 任务日志排序规则
type SortLogByStartTime struct {
	SortOrder int `bson:"startTime"` // {startTime: -1}
}

// BuildResponse 应答方法
func BuildResponse(errno int, msg string, data interface{}) (resp []byte, err error) {
	// 1, 定义一个response
	var (
		response Response
	)

	response.Errno = errno
	response.Msg = msg
	response.Data = data

	// 2, 序列化json
	resp, err = json.Marshal(response)
	return
}

// UnpackJob 反序列化Job
func UnpackJob(value []byte) (ret *Job, err error) {
	var (
		job *Job
	)

	job = &Job{}
	if err = json.Unmarshal(value, job); err != nil {
		return
	}
	ret = job
	return
}

// BuildJobSchedulePlan 构造任务执行计划
func BuildJobSchedulePlan(job *Job) (jobSchedulePlan *JobSchedulePlan, err error) {
	var (
		runTime time.Time
	)

	runTime, _ = time.ParseInLocation("2006-01-02 15:04:05", job.RunAt, time.Local)
	// 生成任务调度计划对象
	jobSchedulePlan = &JobSchedulePlan{
		Job:   job,
		RunAt: runTime,
	}
	return
}

// BuildJobExecuteInfo 构造执行状态信息
func BuildJobExecuteInfo(jobSchedulePlan *JobSchedulePlan) (jobExecuteInfo *JobExecuteInfo) {
	jobExecuteInfo = &JobExecuteInfo{
		Job:      jobSchedulePlan.Job,
		PlanTime: jobSchedulePlan.RunAt, // 计算调度时间
		RealTime: time.Now(),            // 真实调度时间
	}
	jobExecuteInfo.CancelCtx, jobExecuteInfo.CancelFunc = context.WithCancel(context.TODO())
	return
}
